﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Model;

namespace ConAppCore.Test
{
    internal class TestMemoryMappedFile
    {
        public static void Test()
        {
            //Test1();
            TestSpeed();

            //BufferData data = Test2();
            //string str = Test3(data);


            //try
            //{
            //    var mx = Array.MaxLength;
            //    var mod = int.MaxValue - Array.MaxLength;
            //    byte[] buffer = new byte[Array.MaxLength];
            //    data.Stream.Read(buffer, 0, (int)data.Length);
            //}
            //catch (ObjectDisposedException)
            //{

            //}
        }

        private static void TestSpeed()
        {
            try
            {
                //byte[] bufferData = File.ReadAllBytes(@"D:\Ftp\OfficeSoft\Office\SW_DVD5_Office_Professional_Plus_2013_64Bit_ChnSimp_MLF_X18-55285.ISO");
                byte[] bufferData = File.ReadAllBytes(@"D:\Soft\AdobeAudition2019SP.iso");
                int count = 10;
                Stopwatch stopwatch = new Stopwatch();

                stopwatch.Start();
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(@"D:\Temp\mmf.dat", FileMode.CreateNew, "mmf", (long)bufferData.Length * count, MemoryMappedFileAccess.ReadWrite))
                {
                    using (MemoryMappedViewStream mmvs = mmf.CreateViewStream())
                    {
                        for (int i = 0; i < count; i++)
                        {
                            mmvs.Write(bufferData, 0, bufferData.Length);
                        }
                    }
                }
                stopwatch.Stop();
                Console.WriteLine($"mmf:{stopwatch.Elapsed.TotalMilliseconds}ms");

                stopwatch.Restart();
                using (var fs = new FileStream(@"D:\Temp\fs.dat", FileMode.CreateNew))
                {
                    for (int i = 0; i < count; i++)
                    {
                        fs.Write(bufferData, 0, bufferData.Length);
                    }
                }
                stopwatch.Stop();
                Console.WriteLine($"fs:{stopwatch.Elapsed.TotalMilliseconds}ms");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }


        private static string Test3(DataSource bufferData)
        {
            bufferData.Stream.Position = 0;
            using var stream = bufferData.Stream;
            byte[] buffer = new byte[bufferData.Length];
            stream.Read(buffer, 0, buffer.Length);
            return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        }

        private static DataSource Test2()
        {
            byte[] buffer = Encoding.UTF8.GetBytes("天不下雨,天不刮风,天上有太阳!\r\ni loeve you!");
            string mapName = Guid.NewGuid().ToString();
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew(mapName, buffer.Length, MemoryMappedFileAccess.ReadWrite))
            {
                MemoryMappedViewStream mms = mmf.CreateViewStream();
                mms.Write(buffer, 0, buffer.Length);
                return new DataSource(mms, 0, mms.Position);
            }
        }


        private static void Test1()
        {
            string filePath = @"D:\tmp\mmf.dat";
            //MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open, "ImgA");
            using MemoryMappedFile mmf = MemoryMappedFile.CreateNew("ABC", 100, MemoryMappedFileAccess.ReadWrite);
            // Create a random access view, from the 256th megabyte (the offset)
            // to the 768th megabyte (the offset plus length).
            using MemoryMappedViewAccessor accessor1 = mmf.CreateViewAccessor();

            long pos = 0;
            var step = sizeof(char);

            accessor1.Write(pos, 'a');
            pos += step;

            accessor1.Write(pos, 'b');
            accessor1.Flush();

            pos = 0;
            var ch00 = accessor1.ReadChar(pos);
            pos += step;
            var ch01 = accessor1.ReadChar(pos);


            pos = 0;
            pos += step * 2;
            using MemoryMappedViewAccessor accessor2 = mmf.CreateViewAccessor();
            accessor2.Write(pos, 'c');
            accessor2.Flush();

            var ch3 = accessor1.ReadChar(pos);

            pos = 0;
            var ch1 = accessor2.ReadChar(pos);
            pos += step;
            var ch2 = accessor2.ReadChar(pos);

            using MemoryMappedViewStream mms = mmf.CreateViewStream();
            mmf.Dispose();
            var reader = new BinaryReader(mms);
            char[] chs = reader.ReadChars(10);
        }


    }
}

